'use strict'

// https://github.com/timoxley/keycode/blob/master/index.js
// Source: http://jsfiddle.net/vWx8V/
// http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes
/**
 * @module Editor
 */

/**
 * @method KeyCode
 * @param {number|string} key - Can be number(key-code) or string(key-name)
 * @return {number|string}
 *
 * Convenience method returns corresponding value for given keyName or keyCode.
 */

var exports = function(searchInput) {
    // Keyboard Events
    if (searchInput && 'object' === typeof searchInput) {
        let hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode
        if (hasKeyCode) searchInput = hasKeyCode
    }

    // Numbers
    if ('number' === typeof searchInput) return names[searchInput]

    // Everything else (cast to string)
    let search = String(searchInput)

    // check codes
    let foundNamedKey = codes[search.toLowerCase()]
    if (foundNamedKey) return foundNamedKey

    // check aliases
    foundNamedKey = aliases[search.toLowerCase()]
    if (foundNamedKey) return foundNamedKey

    // weird character?
    if (search.length === 1) return search.charCodeAt(0)

    return undefined
}

// Get keycode by key name
// exports.code['enter'] // => 13

let codes = exports.code = exports.codes = {
    'backspace': 8,
    'tab': 9,
    'enter': 13,
    'shift': 16,
    'ctrl': 17,
    'alt': 18,
    'pause/break': 19,
    'caps lock': 20,
    'esc': 27,
    'space': 32,
    'page up': 33,
    'page down': 34,
    'end': 35,
    'home': 36,
    'left': 37,
    'up': 38,
    'right': 39,
    'down': 40,
    'insert': 45,
    'delete': 46,
    'command': 91,
    'right click': 93,
    'numpad *': 106,
    'numpad +': 107,
    'numpad -': 109,
    'numpad .': 110,
    'numpad /': 111,
    'num lock': 144,
    'scroll lock': 145,
    'my computer': 182,
    'my calculator': 183,
    ';': 186,
    '=': 187,
    ',': 188,
    '-': 189,
    '.': 190,
    '/': 191,
    '`': 192,
    '[': 219,
    '\\': 220,
    ']': 221,
    "'": 222
}

// Helper aliases

let aliases = exports.aliases = {
    'windows': 91,
    '⇧': 16,
    '⌥': 18,
    '⌃': 17,
    '⌘': 91,
    'ctl': 17,
    'control': 17,
    'option': 18,
    'pause': 19,
    'break': 19,
    'caps': 20,
    'return': 13,
    'escape': 27,
    'spc': 32,
    'pgup': 33,
    'pgdn': 33,
    'ins': 45,
    'del': 46,
    'cmd': 91
}

// Programatically add the following

// lower case chars
for (let i = 97; i < 123; i++) codes[String.fromCharCode(i)] = i - 32

// numbers
for (let i = 48; i < 58; i++) codes[i - 48] = i

// function keys
for (let i = 1; i < 13; i++) codes['f' + i] = i + 111

// numpad keys
for (let i = 0; i < 10; i++) codes['numpad ' + i] = i + 96

// Get by code
// exports.name[13] // => 'Enter'

let names = exports.names = exports.title = {} // title for backward compat

// Create reverse mapping
for (let i in codes) names[codes[i]] = i

// Add aliases
for (let alias in aliases) {
    codes[alias] = aliases[alias]
}

let KeyCodes = exports